require 'date'
class Uploader
  STAT_MAP = {
      "0" => :SUCCESS,
      "1" => "文件大小超出 upload_max_filesize 限制",
      "2" => "文件大小超出 MAX_FILE_SIZE 限制",
      "3" => "文件未被完整上传",
      "4" => "没有文件被上传",
      "5" => "上传文件为空",
      "ERROR_TMP_FILE" => "临时文件错误",
      "ERROR_TMP_FILE_NOT_FOUND" => "找不到临时文件",
      "ERROR_SIZE_EXCEED" => "文件大小超出网站限制",
      "ERROR_TYPE_NOT_ALLOWED" => "文件类型不允许",
      "ERROR_CREATE_DIR" => "目录创建失败",
      "ERROR_DIR_NOT_WRITEABLE" => "目录没有写权限",
      "ERROR_FILE_MOVE" => "文件保存时出错",
      "ERROR_FILE_NOT_FOUND" => "找不到上传文件",
      "ERROR_WRITE_CONTENT" => "写入文件内容错误",
      "ERROR_UNKNOWN" => "未知错误",
      "ERROR_DEAD_LINK" => "链接不可用",
      "ERROR_HTTP_LINK" => "链接不是http链接",
      "ERROR_HTTP_CONTENTTYPE" => "链接contentType不正确",
      "INVALID_URL" => "非法 URL",
      "INVALID_IP" => "非法 IP"
  }

  def initialize (file_field,config,type,params)
    @file_field = file_field
    @config = config
    @type = type
    @params = params
    if @type == :remote
      saveRemote()
    elsif @type == :base64
      upBase64()
    else
      upFile()
    end
  end

  private
    def upFile
      @file = @params[@file_field]
      if !@file
        @stateInfo = getStateInfo("ERROR_FILE_NOT_FOUND")
        return
      end

      if !File.exist?(@file.tempfile.path)
        @stateInfo = getStateInfo("ERROR_TMP_FILE_NOT_FOUND")
        return
      end
      #需检测是否是上传来的文件

      @oriName = @file.original_filename
      @fileSize = @file.size
      @fileType = getFileExt
      @fullName = getFullName
      @filePath = getFilePath
      @fileName = @oriName
      @dirname = @filePath.slice(0,@filePath.rindex('/'))

      if !checkSize
        @stateInfo = getStateInfo("ERROR_SIZE_EXCEED")
        return
      end

      if !checkType
        @stateInfo = getStateInfo("ERROR_TYPE_NOT_ALLOWED")
      end

      if !Dir.exist?(@dirname) && !FileUtils.mkpath(@dirname,:mode => 0777)
        @stateInfo = getStateInfo("ERROR_CREATE_DIR")
        return
      elsif !File.writable?(@dirname)
        @stateInfo = getStateInfo("ERROR_DIR_NOT_WRITEABLE")
        return
      end

      if !(FileUtils.move(@file.tempfile,@filePath) && File.exist?(@filePath))
        @stateInfo = getStateInfo("ERROR_FILE_MOVE")
        return
      else
        @stateInfo = getStateInfo("0")
      end


    end






    def getStateInfo error_code
      return STAT_MAP.has_key?(error_code) ? STAT_MAP[error_code] : STAT_MAP[:ERROR_UNKNOWN]
    end
    #获取文件扩展名
    def getFileExt
      File.extname(@oriName)
    end
    #重命名文件 根据格式
    def getFullName
      now=DateTime.now
      format = @config[:pathFormat]
      format["{yyyy}"]=now.year.to_s
      format["{mm}"]=now.strftime('%m')
      format["{dd}"]=now.strftime('%d')
      format["{time}"]=now.strftime('%H-%M-%S')
      random = Random.rand(999999999999).to_s+Random.rand(999999999999).to_s+Random.rand(999999999999).to_s
      if format.match(/\{rand:(\d*)\}/)
        format[/\{rand:\d*\}/]=random.slice(0,$1.to_i).to_s
      end
      format["{filename}"]=@oriName
      return format
    end

    def getFilePath
      full_name = @fullName
      if full_name.slice(0,1) != '/'
        full_name = '/' + full_name
      end
      return Rails.root.to_s + full_name
    end

    def checkType
      return @config[:allowFiles].include?(@fileType)
    end

    def checkSize
      return @fileSize <= @config[:maxSize]
    end

  public def getFileInfo
      return {
          "state" => @stateInfo,
          "url" => @fullName.slice('/app/'.length-1,@fullName.length).sub(/\/ueditor/,''),
          "title" => @fileName,
          "original" => @oriName,
          "type" => @fileType,
          "size" => @fileSize
      }
  end
end